<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>模板</title>
  </head>
  <body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>

    <!-- 引入react核心库 -->
    <script
      type="text/javascript"
      src="../js/17.0.1/react.development.js"
    ></script>
    <!-- 引入react-dom，用于支持react操作DOM -->
    <script
      type="text/javascript"
      src="../js/17.0.1/react-dom.development.js"
    ></script>
    <!-- 引入babel，用于将jsx转换成js -->
    <script type="text/javascript" src="../js/17.0.1/babel.min.js"></script>
    <script type="text/babel">
      /**
       * 1.初始化阶段：由ReactDOM.render()触发--初次渲染
       *    1)constructor()
       *    2)getDerivedStateFromProps
       *    3)render()
       *    4)componentDidMount()
       * 2.更新阶段：由组件内部的this.setState()或父组件重新render触发
       *    1)getDerivedStateFromProps()
       *    2)shouldComponentUpdate()
       *    3)render()
       *    4)getSnapshotBeforeUpdate()
       *    5)componentDidUpdate()
       * 3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
       *    1)compoenntWillUnmount()
       */
      class Count extends React.Component {
        //-----------------------创建时--------------------------
        //构造器
        constructor(props) {
          console.log("Count-constructor");
          super(props);
          //初始化状态
          this.state = {
            count: 0,
          };
        }

        /**
         * 该方法使用场景罕见，使用概率低
         * 返回的对象，如果键和state对应，那么将会覆盖掉state中的值，一直以返回的值为准
         * 官方文档：即state的值在任何时候都取决于props
         */
        static getDerivedStateFromProps(props, state) {
          console.log("getDerivedStateFromProps", props, "----", state);
          //   return props;
          return null;
        }

        //加1按钮回调
        add = () => {
          //获取原状态
          const { count } = this.state;
          //更新状态
          this.setState({
            count: count + 1,
          });
        };

        //卸载组件按钮的回调
        death = () => {
          ReactDOM.unmountComponentAtNode(document.querySelector("#test"));
        };

        //强制更新按钮的回调
        force = () => {
          this.forceUpdate();
        };

        //挂载组件
        render() {
          console.log("Count-render");
          return (
            <div>
              <h2>当前求和为：{this.state.count}</h2>
              <button onClick={this.add}>点击+1</button>
              <button onClick={this.death}>卸载组件</button>
              <button onClick={this.force}>强制更新</button>
            </div>
          );
        }

        //在更新之前获取快照（修改前的原始值，传给下游的componentDidUpdate方法使用）
        getSnapshotBeforeUpdate() {
          console.log("getSnapshotBeforeUpdate...");
          return "snapshot这里传下去给componentDidUpdate";
        }

        //组件挂载完成后的狗子
        componentDidMount() {
          console.log("Count-componentDidMount");
        }

        //组件将要卸载之前的钩子
        componentWillUnmount() {
          console.log("Count-componentWillUnmount");
        }

        //---------------------------修改时--------------------------------
        /**
         * 控制组件更新的'阀门'
         * 当更新状态的时候，首先会调用该方法，该方法返回一个boolean值
         * 返回true，则可以继续执行下去修改值
         * 返回false，则修改失败,后续方法不再执行
         */
        shouldComponentUpdate() {
          console.log("Count-shouldComponentUpdate");
          return true;
        }

        //组件更新后的钩子
        componentDidUpdate(preProps, preState, snapshot) {
          console.log("Count-componentDidUpdate", preProps, preState, snapshot);
        }
      }

      ReactDOM.render(<Count count={22} />, document.querySelector("#test"));
    </script>
  </body>
</html>
